package edu.map.aamas.gui;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;

import edu.map.aamas.rnn.RNN;
import edu.map.aamas.rnn.RnnListener;

public class PondPanel extends JPanel implements RnnListener {

	private static final long serialVersionUID = 1L;
	public Tadpole t = Tadpole.getInstance();
	private BufferedImage traj;
	private int lastWidth = 0, lastHeight = 0;
	private double lastX = t.getPosition().x, lastY = t.getPosition().y;
	private double zoom = 1.0;
	private double leftX = 0.0;
	private double topY = 0.0;
	private static PondPanel instance = null;
	
	private PondPanel() {
		setBackground(new Color(180, 220, 120));		
	}
	
	public static PondPanel getInstance() {
		if (instance == null)
			instance = new PondPanel();
		
		return instance;
	}
	
	@Override
	public void paint(Graphics g) {
		super.paint(g);
		
		if (traj == null || lastHeight != getHeight() || lastWidth != getWidth()) {
			traj = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
			lastHeight = getHeight();
			lastWidth = getWidth();			
		}
		((Graphics2D)g).setTransform(new AffineTransform());
		Graphics2D g2d = (Graphics2D)traj.getGraphics();
		
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2d.setStroke(new BasicStroke(2f));
		g2d.setColor(new Color(0,0,255,50));
		if (Math.abs(lastX - t.getPaintedPosition().x) < getWidth() - 10 && Math.abs(lastY - t.getPaintedPosition().y) < getHeight()-10)
			g2d.draw(new Line2D.Double(lastX, lastY, t.getPaintedPosition().x, t.getPaintedPosition().y));
		lastX = t.getPaintedPosition().x;
		lastY = t.getPaintedPosition().y;
		g2d = (Graphics2D)g;
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);		
		t.paint(this, g2d);
		g2d.setTransform(new AffineTransform());
		g2d.drawImage(traj, 0, 0, this);		
		g2d.setColor(Color.white);
		g2d.drawString("("+(int)t.getPosition().x+", "+(int)t.getPosition().y+")",5, 15);
	}
	
	public void rnnUpdated(RNN rnr) {
		t.applyForce(rnr.getDiffC0C1(), getWidth(), getHeight());
		repaint();
	}
	

	public void rnnRestarted(RNN rnr) {
		traj = null;
		t.resetInstance();
		lastX = t.getPosition().x;
		lastY = t.getPosition().y;
	}
	
	public static void main(String[] args) throws Exception {
		JFrame test = new JFrame("test");
		PondPanel tp = new PondPanel();
		tp.t.setAngle(Math.toRadians(90));
		tp.setBackground(new Color(180, 220, 120));
		tp.t.setPosition(200, 200);
		test.add(tp);
		test.setSize(400, 400);
		test.setVisible(true);
		test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		RNN rnr = RNN.getInstance(32);
		
		rnr.addRnrListener(tp);
		
		while (true) {
			rnr.update();
			Thread.sleep(10);
		}		
	}

	public double getZoom() {
		return zoom;
	}

	public void setZoom(double zoom) {
		this.zoom = zoom;
	}

	public double getLeftX() {
		return leftX;
	}

	public void setLeftX(double leftX) {
		this.leftX = leftX;
	}

	public double getTopY() {
		return topY;
	}

	public void setTopY(double topY) {
		this.topY = topY;
	}
}
